home *** CD-ROM | disk | FTP | other *** search
/ MacWorld 2003 August / MW 8 2003 CD1.iso / Inside Macworld / Product News / gimp-1.2.4.sit / gimp-1.2.4 / plug-ins / common / winclipboard.c < prev    next >
Encoding:
C/C++ Source or Header  |  2002-12-16  |  17.8 KB  |  695 lines

  1. /*
  2.  * WinClipboard Win32 Windoze Copy&Paste Plug-in
  3.  * Copyright (C) 1999 Hans Breuer
  4.  * Hans Breuer, Hans@Breuer.org
  5.  * 08/07/99
  6.  *
  7.  * This program is free software; you can redistribute it and/or modify
  8.  * it under the terms of the GNU General Public License as published by
  9.  * the Free Software Foundation; either version 2 of the License, or
  10.  * (at your option) any later version.
  11.  *
  12.  * This program is distributed in the hope that it will be useful,
  13.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.  * GNU General Public License for more details.
  16.  *
  17.  * You should have received a copy of the GNU General Public License
  18.  * along with this program; if not, write to the Free Software
  19.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  20.  *
  21.  * Based on (at least) the following plug-ins:
  22.  *  Header
  23.  *  WinSnap
  24.  *
  25.  * Any suggestions, bug-reports or patches are welcome.
  26.  */
  27.  
  28. #include "config.h"
  29.  
  30. #include <windows.h>
  31. #include <stdlib.h>
  32.  
  33. #include <libgimp/gimp.h>
  34.  
  35. #include "libgimp/stdplugins-intl.h"
  36.  
  37.  
  38. /* History:
  39.  *  
  40.  *   08/07/99 Implementation and release.
  41.  *     08/10/99 Big speed increase by using gimp_tile_cache_size()
  42.  *              Thanks to Kevin Turner's documentation at:
  43.  *              http://www.poboxes.com/kevint/gimp/doc/plugin-doc-2.1.html
  44.  *
  45.  * TODO (maybe):
  46.  *
  47.  *   - Support for 4,2,1 bit bitmaps
  48.  *   - Unsupported formats could be delegated to GIMP Loader (e.g. wmf)
  49.  *   - ...
  50.  */
  51.  
  52. /* How many steps the progress control should do
  53.  */
  54. #define PROGRESS_STEPS 25
  55. #define StepProgress(one,all) \
  56.     (0 == (one % ((all / PROGRESS_STEPS)+1)))
  57.  
  58. /* FIXME: I'll use -1 as IMAGE_NONE. Is it correct ???
  59.  */
  60. #define IMAGE_NONE -1
  61.  
  62. /* Declare some local functions.
  63.  */
  64. static void   query      (void);
  65. static void   run        (gchar      *name,
  66.                           gint        nparams,
  67.                           GimpParam  *param,
  68.                           gint       *nreturn_vals,
  69.                           GimpParam **return_vals);
  70.  
  71. /* Plugin function prototypes
  72.  */
  73. static int CB_CopyImage (gboolean    interactive,
  74.              gint32      image_ID,
  75.              gint32      drawable_ID);
  76.  
  77. static int CB_PasteImage (gboolean   interactive,
  78.               gint32     image_ID,
  79.               gint32     drawable_ID);
  80.  
  81.  
  82. GimpPlugInInfo PLUG_IN_INFO =
  83. {
  84.   NULL,  /* init_proc  */
  85.   NULL,  /* quit_proc  */
  86.   query, /* query_proc */
  87.   run,   /* run_proc   */
  88. };
  89.  
  90.  
  91. MAIN ()
  92.  
  93. static void
  94. query ()
  95. {
  96.   static GimpParamDef copy_args[] =
  97.   {
  98.     { GIMP_PDB_INT32, "run_mode", "Interactive, non-interactive" },
  99.     { GIMP_PDB_IMAGE, "image", "Input image" },
  100.     { GIMP_PDB_DRAWABLE, "drawable", "Drawable to save" }
  101.   };
  102.   static gint ncopy_args = sizeof (copy_args) / sizeof (copy_args[0]);
  103.  
  104.   gimp_install_procedure ("plug_in_clipboard_copy",
  105.                           "copy image to clipboard",
  106.                           "Copies the active drawable to the clipboard.",
  107.                           "Hans Breuer",
  108.                           "Hans Breuer",
  109.                           "1999",
  110.                           N_("<Image>/Edit/Copy to Clipboard"),
  111.                           "INDEXED*, RGB*",
  112.                           GIMP_PLUGIN,
  113.                           ncopy_args, 0,
  114.                           copy_args, NULL);
  115.  
  116.   gimp_install_procedure ("plug_in_clipboard_paste",
  117.                           "paste image from clipboard",
  118.                           "Paste image from clipboard into active image.",
  119.                           "Hans Breuer",
  120.                           "Hans Breuer",
  121.                           "1999",
  122.                           N_("<Image>/Edit/Paste from Clipboard"),
  123.                           "INDEXED*, RGB*",
  124.                           GIMP_PLUGIN,
  125.                           ncopy_args, 0,
  126.                           copy_args, NULL);
  127.  
  128.   gimp_install_procedure ("extension_clipboard_paste",
  129.                           "Get image from clipboard",
  130.                           "Get an image from the Windows clipboard, creating a new image",
  131.                           "Hans Breuer",
  132.                           "Hans Breuer",
  133.                           "1999",
  134.                           N_("<Toolbox>/File/Acquire/From Clipboard"),
  135.                           "",
  136.                           GIMP_EXTENSION,
  137.                           ncopy_args, 0,
  138.                           copy_args, NULL);
  139.  
  140. }
  141.  
  142. static void
  143. run (gchar      *name,
  144.      gint        nparams,
  145.      GimpParam  *param,
  146.      gint       *nreturn_vals,
  147.      GimpParam **return_vals)
  148. {
  149.   static GimpParam values[2];
  150.   GimpRunModeType run_mode;
  151.  
  152.   run_mode = param[0].data.d_int32;
  153.  
  154.   *nreturn_vals = 1;
  155.   *return_vals = values;
  156.   values[0].type = GIMP_PDB_STATUS;
  157.   values[0].data.d_status = GIMP_PDB_CALLING_ERROR;
  158.  
  159.   INIT_I18N();
  160.  
  161.   if (strcmp (name, "plug_in_clipboard_copy") == 0)
  162.     {
  163.       *nreturn_vals = 1;
  164.       if (CB_CopyImage (GIMP_RUN_INTERACTIVE==run_mode,
  165.             param[1].data.d_int32, 
  166.             param[2].data.d_int32))
  167.     values[0].data.d_status = GIMP_PDB_SUCCESS;
  168.       else
  169.     values[0].data.d_status = GIMP_PDB_EXECUTION_ERROR;
  170.     }
  171.   else if (strcmp (name, "plug_in_clipboard_paste") == 0)
  172.     {
  173.       *nreturn_vals = 1;
  174.       if (CB_PasteImage (GIMP_RUN_INTERACTIVE==run_mode,
  175.              param[1].data.d_int32, 
  176.              param[2].data.d_int32))
  177.     values[0].data.d_status = GIMP_PDB_SUCCESS;
  178.       else
  179.     values[0].data.d_status = GIMP_PDB_EXECUTION_ERROR;
  180.     }
  181.   else if (strcmp (name, "extension_clipboard_paste") == 0)
  182.     {
  183.       *nreturn_vals = 1;
  184.       if (CB_PasteImage (GIMP_RUN_INTERACTIVE==run_mode,
  185.              IMAGE_NONE,
  186.              IMAGE_NONE))
  187.     values[0].data.d_status = GIMP_PDB_SUCCESS;
  188.       else
  189.     values[0].data.d_status = GIMP_PDB_EXECUTION_ERROR;
  190.     }
  191. }
  192.  
  193. /* Plugin Function implementation
  194.  */
  195. static int
  196. CB_CopyImage (gboolean interactive,
  197.           gint32   image_ID,
  198.           gint32   drawable_ID)
  199. {
  200.   GimpDrawable *drawable;
  201.   GimpImageType drawable_type;
  202.   GimpPixelRgn pixel_rgn;
  203.   gchar *sStatus = NULL;
  204.  
  205.   int nSizeDIB=0;
  206.   int nSizePal=0;
  207.   int nSizeLine=0; /* DIB lines are 32 bit aligned */
  208.  
  209.   HANDLE hDIB;
  210.   BOOL bRet;
  211.  
  212.   drawable = gimp_drawable_get (drawable_ID);
  213.   drawable_type = gimp_drawable_type (drawable_ID);
  214.   gimp_pixel_rgn_init (&pixel_rgn, drawable, 0, 0, drawable->width, drawable->height, FALSE, FALSE);
  215.  
  216.   /* allocate room for DIB */
  217.   if (GIMP_INDEXED_IMAGE == drawable_type)
  218.     {
  219.       nSizeLine = ((drawable->width-1)/4+1)*4;
  220.       nSizeDIB = sizeof(RGBQUAD) * 256 /* always full color map size */
  221.     + nSizeLine * drawable->height
  222.     + sizeof (BITMAPINFOHEADER);
  223.     }
  224.   else
  225.     {
  226.       nSizeLine = ((drawable->width*3-1)/4+1)*4;
  227.       nSizeDIB = nSizeLine * drawable->height
  228.     + sizeof (BITMAPINFOHEADER);
  229.     }
  230.   
  231.   hDIB = GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE, nSizeDIB);
  232.   if (NULL == hDIB)
  233.     {
  234.       g_message ("Failed to allocate DIB");
  235.       bRet = FALSE;
  236.     }
  237.   
  238.   /* fill header info */
  239.   if (bRet)
  240.     {
  241.       BITMAPINFOHEADER *pInfo;
  242.       
  243.       bRet = FALSE;
  244.       pInfo = GlobalLock (hDIB);
  245.       if (pInfo)
  246.     {
  247.       pInfo->biSize   = sizeof(BITMAPINFOHEADER);
  248.       pInfo->biWidth  = drawable->width;
  249.       pInfo->biHeight = drawable->height;
  250.       pInfo->biPlanes = 1;
  251.       pInfo->biBitCount = (GIMP_INDEXED_IMAGE == drawable_type ? 8 : 24);
  252.       pInfo->biCompression = BI_RGB; /* none */
  253.       pInfo->biSizeImage = 0; /* not calculated/needed */
  254.       pInfo->biXPelsPerMeter =
  255.         pInfo->biYPelsPerMeter = 0;
  256.       /* color map size */
  257.       pInfo->biClrUsed = (GIMP_INDEXED_IMAGE == drawable_type ? 256 : 0);
  258.       pInfo->biClrImportant = 0; /* all */
  259.       
  260.       GlobalUnlock (hDIB);
  261.       bRet = TRUE;
  262.     } /* (pInfo) */
  263.       else
  264.     g_message("Failed to lock DIB Header");
  265.     }
  266.   
  267.   /* fill color map */
  268.   if (bRet && (GIMP_INDEXED_IMAGE == drawable_type))
  269.     {
  270.       char *pBmp;
  271.       
  272.       bRet = FALSE;
  273.       pBmp = GlobalLock (hDIB);
  274.       if (pBmp)
  275.     {
  276.       RGBQUAD *pPal;
  277.       int nColors;
  278.       unsigned char *cmap;
  279.       pPal = (RGBQUAD*)(pBmp + sizeof(BITMAPINFOHEADER));
  280.       nSizePal = sizeof(RGBQUAD) * 256;
  281.       
  282.       /* get the gimp colormap */
  283.       cmap = gimp_image_get_cmap (image_ID, &nColors);
  284.       
  285.       if (cmap)
  286.         {
  287.           int i;
  288.           for (i = 0; (i < 256) && (i < nColors); i++)
  289.         {
  290.           pPal[i].rgbReserved = 0; /* is this alpha? */
  291.           pPal[i].rgbRed      = cmap[3*i];
  292.           pPal[i].rgbGreen    = cmap[3*i+1];
  293.           pPal[i].rgbBlue     = cmap[3*i+2];
  294.         }
  295.           
  296.           g_free(cmap);
  297.           bRet = TRUE;
  298.         } /* (cmap) */
  299.       else
  300.         g_message ("Can't get color map");
  301.       GlobalUnlock (hDIB);
  302.     } /* (pBmp) */
  303.       else
  304.     g_message ("Failed to lock DIB Palette");
  305.     } /* indexed */
  306.   
  307.   /* following the slow part ... */
  308.   if (interactive)
  309.     gimp_progress_init (_("Copying ..."));
  310.   
  311.   /* speed it up with: */
  312.   gimp_tile_cache_size (drawable->width * gimp_tile_height () * drawable->bpp);
  313.   
  314.   /* copy data to DIB */
  315.   if (bRet)
  316.     {
  317.       unsigned char *pData;
  318.       
  319.       bRet = FALSE;
  320.       pData = GlobalLock (hDIB);
  321.       
  322.       if (pData)
  323.     {
  324.       unsigned char *pLine;
  325.       
  326.       /* calculate real offset */
  327.       pData += (sizeof(BITMAPINFOHEADER) + nSizePal);
  328.       
  329.       pLine = g_new (guchar, drawable->width * drawable->bpp);
  330.       
  331.       if (GIMP_INDEXED_IMAGE == drawable_type)
  332.         {
  333.           int x, y;
  334.           for (y = 0; y < drawable->height; y++)
  335.         {
  336.           if ((interactive) && (StepProgress(y,drawable->height)))
  337.             gimp_progress_update ((double)y / drawable->height);
  338.           
  339.           gimp_pixel_rgn_get_row (&pixel_rgn, pLine, 0, 
  340.                       drawable->height-y-1, /* invert it */
  341.                       drawable->width);
  342.           for (x = 0; x < drawable->width; x++)
  343.             pData[x+y*nSizeLine] = pLine[x*drawable->bpp];
  344.         }
  345.         }
  346.       else
  347.         {
  348.           int x, y;
  349.           for (y = 0; y < drawable->height; y++)
  350.         {
  351.           if ((interactive) && (StepProgress(y,drawable->height)))
  352.             gimp_progress_update ((double)y / drawable->height);
  353.           
  354.           gimp_pixel_rgn_get_row (&pixel_rgn, pLine, 0, 
  355.                       drawable->height-y-1, /* invert it */
  356.                       drawable->width);
  357.           for (x = 0; x < drawable->width; x++)
  358.             {
  359.               /* RGBQUAD: blue, green, red, reserved */
  360.               pData[x*3+y*nSizeLine]   = pLine[x*drawable->bpp+2]; /* blue */
  361.               pData[x*3+y*nSizeLine+1] = pLine[x*drawable->bpp+1]; /* green */
  362.               pData[x*3+y*nSizeLine+2] = pLine[x*drawable->bpp];   /* red */
  363.               /*pData[x+y*drawable->width*3+3] = 0;*/          /* reserved */
  364.             }
  365.         }
  366.         }
  367.       
  368.       g_free (pLine);
  369.       bRet = TRUE;
  370.       
  371.       GlobalUnlock (hDIB);
  372.     } /* (pData) */
  373.       else
  374.     g_message("Failed to lock DIB Data");
  375.     } /* copy data to DIB */
  376.   
  377.   /* copy DIB to ClipBoard */
  378.   if (bRet)      
  379.     {
  380.       if (!OpenClipboard (NULL))
  381.     {
  382.       g_message ("Cannot open the Clipboard!");
  383.       bRet = FALSE;
  384.     }
  385.       else
  386.     {
  387.       if (bRet && !EmptyClipboard ())
  388.         {
  389.           g_message ("Cannot empty the Clipboard");
  390.           bRet = FALSE;
  391.         }
  392.       if (bRet)
  393.         {
  394.           if (NULL != SetClipboardData (CF_DIB, hDIB))
  395.         hDIB = NULL; /* data now owned by clipboard */
  396.           else
  397.         g_message ("Failed to set clipboard data ");
  398.         }
  399.       
  400.       if (!CloseClipboard ())
  401.         g_message ("Failed to close Clipboard");
  402.     }
  403.     }
  404.   /* done */
  405.   if (hDIB)
  406.     GlobalFree(hDIB);
  407.   
  408.   gimp_drawable_detach (drawable);
  409.   
  410.   return bRet;
  411. } /* CB_CopyImage */
  412.  
  413. static void
  414. decompose_mask (guint32  mask,
  415.         gint    *shift,
  416.         gint    *prec)
  417. {
  418.   *shift = 0;
  419.   *prec = 0;
  420.  
  421.   while (!(mask & 0x1))
  422.     {
  423.       (*shift)++;
  424.       mask >>= 1;
  425.     }
  426.  
  427.   while (mask & 0x1)
  428.     {
  429.       (*prec)++;
  430.       mask >>= 1;
  431.     }
  432. }
  433.  
  434. static int
  435. CB_PasteImage (gboolean interactive,
  436.                gint32   image_ID,
  437.                gint32   drawable_ID)
  438. {
  439.   UINT fmt;
  440.   BOOL bRet=TRUE;
  441.   HANDLE hDIB;
  442.   BITMAPINFO *pInfo;
  443.   gint32 nWidth  = 0;
  444.   gint32 nHeight = 0;
  445.   gint32 nBitsPS = 0;
  446.   gint32 nColors = 0;
  447.   guint32 maskR;
  448.   guint32 maskG;
  449.   guint32 maskB;
  450.   gint shiftR;
  451.   gint shiftG;
  452.   gint shiftB;
  453.   gint precR;
  454.   gint precG;
  455.   gint precB;
  456.   gint maxR;
  457.   gint maxG;
  458.   gint maxB;
  459.  
  460.   if (!OpenClipboard (NULL))
  461.     {
  462.       g_message("Failed to open clipboard");
  463.       return FALSE;
  464.     }
  465.   
  466.   fmt = EnumClipboardFormats (0);
  467.   while ((CF_BITMAP != fmt) && (CF_DIB != fmt) && (0 != fmt))
  468.     fmt = EnumClipboardFormats (fmt);
  469.   
  470.   if (0 == fmt) 
  471.     {
  472.       g_message (_("Unsupported format or Clipboard empty!"));
  473.       bRet = FALSE;
  474.     }
  475.   
  476.   /* there is something supported */
  477.   if (bRet) 
  478.     {
  479.       hDIB = GetClipboardData (CF_DIB);
  480.       
  481.       if (NULL == hDIB)
  482.     {
  483.       g_message (_("Can't get Clipboard data."));
  484.       bRet = FALSE;
  485.     }
  486.     }
  487.   
  488.   /* read header */
  489.   if (bRet && hDIB) 
  490.     {
  491.       pInfo = GlobalLock (hDIB);
  492.       if (NULL == pInfo)
  493.     {
  494.       g_message ("Can't lock Clipboard data!");
  495.       bRet = FALSE;
  496.     }
  497.       
  498.       if (bRet && pInfo->bmiHeader.biCompression == BI_BITFIELDS)
  499.     {
  500.       maskR = ((DWORD *)pInfo->bmiColors)[0];
  501.       maskG = ((DWORD *)pInfo->bmiColors)[1];
  502.       maskB = ((DWORD *)pInfo->bmiColors)[2];
  503.       decompose_mask (maskR, &shiftR, &precR);
  504.       maxR = (1 << precR) - 1;
  505.       decompose_mask (maskG, &shiftG, &precG);
  506.       maxG = (1 << precG) - 1;
  507.       decompose_mask (maskB, &shiftB, &precB);
  508.       maxB = (1 << precB) - 1;
  509.     }
  510.  
  511.       if ((bRet) &&
  512.       ((pInfo->bmiHeader.biSize != sizeof(BITMAPINFOHEADER)
  513.         || (pInfo->bmiHeader.biCompression != BI_RGB
  514.         && pInfo->bmiHeader.biCompression != BI_BITFIELDS))))
  515.     {
  516.       g_message ("Unsupported bitmap format (%d)!", 
  517.              pInfo->bmiHeader.biCompression);
  518.       bRet = FALSE;
  519.     }
  520.       
  521.       if (bRet && pInfo) 
  522.     {
  523.       nWidth  = pInfo->bmiHeader.biWidth;
  524.       nHeight = pInfo->bmiHeader.biHeight;
  525.       nBitsPS = pInfo->bmiHeader.biBitCount;
  526.       nColors = pInfo->bmiHeader.biClrUsed;
  527.     }
  528.     }
  529.   
  530.   if ((0 != nWidth) && (0 != nHeight))
  531.     {
  532.       GimpDrawable *drawable;
  533.       GimpPixelRgn pixel_rgn;
  534.       guchar *pData;
  535.       GimpParam *params;
  536.       gint retval;
  537.       gboolean bIsNewImage = TRUE;
  538.       gint oldBPP = 0;
  539.       guchar *pLine;
  540.       RGBQUAD *pPal;
  541.       const int nSizeLine = ((nWidth*(nBitsPS/8)-1)/4+1)*4;
  542.       
  543.       /* Check if clipboard data and existing image are compatible */
  544.       if (IMAGE_NONE != drawable_ID)
  545.     {
  546.       drawable = gimp_drawable_get (drawable_ID);
  547.       oldBPP = drawable->bpp;
  548.       gimp_drawable_detach (drawable);
  549.     }
  550.       
  551.       if ((IMAGE_NONE == image_ID)
  552.       || (3 != oldBPP) || (24 != nBitsPS))
  553.     {
  554.       /* create new image */
  555.       image_ID = gimp_image_new (nWidth, nHeight, nBitsPS <= 8 ? GIMP_INDEXED : GIMP_RGB);
  556.       gimp_image_undo_disable(image_ID);
  557.       drawable_ID = gimp_layer_new (image_ID, _("Background"), nWidth, nHeight, 
  558.                     nBitsPS <= 8 ? GIMP_INDEXED_IMAGE : GIMP_RGB_IMAGE, 
  559.                     100, GIMP_NORMAL_MODE);
  560.     }
  561.       else
  562.     {
  563.       /* ??? gimp_convert_rgb (image_ID);
  564.        */
  565.       drawable_ID = gimp_layer_new (image_ID, _("Pasted"), nWidth, nHeight, 
  566.                     nBitsPS <= 8 ? GIMP_INDEXED_IMAGE : GIMP_RGB_IMAGE, 
  567.                     100, GIMP_NORMAL_MODE);
  568.       bIsNewImage = FALSE;
  569.     }
  570.       
  571.       gimp_image_add_layer (image_ID, drawable_ID, -1);
  572.       drawable = gimp_drawable_get (drawable_ID);
  573.       
  574.       gimp_pixel_rgn_init (&pixel_rgn, drawable, 0, 0, drawable->width, drawable->height, FALSE, FALSE);
  575.       
  576.       /* following the slow part ... */
  577.       if (interactive)
  578.     gimp_progress_init (_("Pasting..."));
  579.       
  580.       /* adjust pointer */
  581.       pPal  = pInfo->bmiColors;
  582.       if (pInfo->bmiHeader.biCompression == BI_BITFIELDS)
  583.         pData = (guchar*)pPal + sizeof(DWORD) * 3;
  584.       else
  585.         pData = (guchar*)pPal + sizeof(RGBQUAD) * nColors;
  586.       
  587.       /* create palette */
  588.       if (0 != nColors)
  589.     {
  590.       int c;
  591.       guchar *cmap;
  592.       
  593.       cmap = g_new (guchar, nColors*3);
  594.       for (c = 0; c < nColors; c++)
  595.         {
  596.           cmap[c*3]   = pPal[c].rgbRed;
  597.           cmap[c*3+1] = pPal[c].rgbGreen;
  598.           cmap[c*3+2] = pPal[c].rgbBlue;
  599.         }
  600.       gimp_image_set_cmap (image_ID, cmap, nColors);
  601.       g_free (cmap);
  602.     }
  603.       
  604.       /* speed it up with: */
  605.       gimp_tile_cache_size (drawable->width * gimp_tile_height () * drawable->bpp );
  606.       
  607.       /* change data format and copy data */
  608.       if ((24 == nBitsPS && pInfo->bmiHeader.biCompression == BI_RGB)
  609.       || (pInfo->bmiHeader.biCompression == BI_BITFIELDS))
  610.     {
  611.       int y;
  612.       const int bps = nBitsPS / 8;
  613.       pLine = g_new (guchar, drawable->width*drawable->bpp);
  614.  
  615.       for (y = 0; y < drawable->height; y++)
  616.         {
  617.           int x;
  618.           
  619.           if ((interactive) && (StepProgress (y, drawable->height)))
  620.         gimp_progress_update ((double)y / drawable->height);
  621.           
  622.           if (pInfo->bmiHeader.biCompression == BI_RGB)
  623.         for (x = 0; x < drawable->width; x++)
  624.           {
  625.             pLine[x*drawable->bpp]   = pData[y*nSizeLine+x*bps+2];
  626.             pLine[x*drawable->bpp+1] = pData[y*nSizeLine+x*bps+1];
  627.             pLine[x*drawable->bpp+2] = pData[y*nSizeLine+x*bps];
  628.           }
  629.           else 
  630.         for (x = 0; x < drawable->width; x++)
  631.           {
  632.             guint dw;
  633.  
  634.             if (nBitsPS == 32)
  635.               dw = *((DWORD *)(pData + y*nSizeLine + x*4));
  636.             else
  637.               dw = *((WORD *)(pData + y*nSizeLine + x*2));
  638.             pLine[x*drawable->bpp]   = (255 * ((dw & maskR) >> shiftR)) / maxR;
  639.             pLine[x*drawable->bpp+1] = (255 * ((dw & maskG) >> shiftG)) / maxG;
  640.             pLine[x*drawable->bpp+2] = (255 * ((dw & maskB) >> shiftB)) / maxB;
  641.           }
  642.           
  643.           /* copy data to GIMP */
  644.           gimp_pixel_rgn_set_rect (&pixel_rgn, pLine, 0, drawable->height-1-y, drawable->width, 1);
  645.         }
  646.       g_free (pLine);
  647.     }
  648.       else if (8 == nBitsPS)
  649.     {
  650.       int y;
  651.       /* copy line by line */
  652.       for (y = 0; y < drawable->height; y++)
  653.         {
  654.           if ((interactive) && (StepProgress (y, drawable->height)))
  655.         gimp_progress_update ((double)y / drawable->height);
  656.           
  657.           pLine = pData + y*nSizeLine; /* adjust pointer */
  658.           gimp_pixel_rgn_set_row (&pixel_rgn, pLine, 0, drawable->height-1-y, drawable->width);
  659.         }
  660.     }
  661.       else
  662.     {
  663.       /* copy and shift bits */
  664.       g_message ("%d bits per sample not yet supported!", nBitsPS);
  665.     }
  666.       
  667.       gimp_drawable_flush (drawable);
  668.       gimp_drawable_detach (drawable);
  669.       
  670.       /* Don't forget to display the new image! */
  671.       if (bIsNewImage)
  672.     gimp_display_new (image_ID);
  673.       else
  674.     {
  675.       gimp_layer_set_visible (drawable_ID, TRUE);
  676.       gimp_displays_flush ();
  677.     }
  678.     }
  679.   
  680.   /* done */
  681.   /* clear clipboard? */
  682.   if (NULL != hDIB)
  683.     {
  684.       GlobalUnlock (pInfo);
  685.       GlobalFree (hDIB);
  686.     }
  687.   
  688.   CloseClipboard ();
  689.   
  690.   /* shouldn't this be done by caller?? */
  691.   gimp_image_undo_enable (image_ID);
  692.  
  693.   return bRet;
  694. } /* CB_PasteImage */
  695.